package es.gesfutbol.dao;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Hibernate;
import org.hibernate.LockMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Transactional;

import es.gesfutbol.domini.implementacio.Equip;
import es.gesfutbol.domini.implementacio.Estadi;
import es.gesfutbol.domini.implementacio.Jornada;
import es.gesfutbol.domini.implementacio.Partit;
import es.gesfutbol.util.HibernateDao;
import es.gesfutbol.util.HibernateHelper;

public class PartitDao extends HibernateDao<Partit, Long> implements IPartitDao{

	@Override
	@Transactional(readOnly=false)
	public void delete(Long idPartit) {
		//Obtenim l'equip a eliminar.
		Partit partit = this.findById(idPartit);
		//Eliminem l'equip.
		this.delete(partit);		
	}

	
	@Transactional(readOnly = true)
	public Partit deproxy (Partit partit){
		//Estadi
		Estadi estadi = partit.getEstadi();
		Hibernate.initialize(estadi);
		estadi = HibernateHelper.deproxy(estadi, Estadi.class);
		partit.setEstadi(estadi);
		
		//Equip Local
		Equip equipLocal = partit.getEquipLocal();
		Hibernate.initialize(equipLocal);
		equipLocal = HibernateHelper.deproxy(equipLocal, Equip.class);
		partit.setEquipLocal(equipLocal);
		
		//Equip Visitant
		Equip equipVisitant = partit.getEquipVisitant();
		Hibernate.initialize(equipVisitant);
		equipVisitant = HibernateHelper.deproxy(equipVisitant, Equip.class);
		partit.setEquipVisitant(equipVisitant);
		
		return partit;
	}
	
	@SuppressWarnings("deprecation")
	@Transactional(readOnly = true)
	public Partit deproxylock(Partit partit){
		this.getSessionFactory().getCurrentSession().lock(partit, LockMode.NONE);
		//Estadi
		Estadi estadi = partit.getEstadi();
		Hibernate.initialize(estadi);
		estadi = HibernateHelper.deproxy(estadi, Estadi.class);
		partit.setEstadi(estadi);
		
		//Equip Local
		Equip equipLocal = partit.getEquipLocal();
		Hibernate.initialize(equipLocal);
		equipLocal = HibernateHelper.deproxy(equipLocal, Equip.class);
		partit.setEquipLocal(equipLocal);
		
		//Equip Visitant
		Equip equipVisitant = partit.getEquipVisitant();
		Hibernate.initialize(equipVisitant);
		equipVisitant = HibernateHelper.deproxy(equipVisitant, Equip.class);
		partit.setEquipVisitant(equipVisitant);
		return partit;
	}
	
	@SuppressWarnings("deprecation")
	@Transactional(readOnly = true)
	public Set<Partit> deproxylist(Set<Partit> partits){
		
		Iterator<Partit> itPartit = partits.iterator();
		Set<Partit> partits2 = new HashSet<Partit>();
		while (itPartit.hasNext()) {
			Partit partit = itPartit.next();
			this.getSessionFactory().getCurrentSession().lock(partit, LockMode.NONE);
			Equip equipLocal = partit.getEquipLocal();
			Equip equipVisitant = partit.getEquipVisitant();
			Estadi estadi = partit.getEstadi();
			Hibernate.initialize(equipLocal);
			equipLocal = HibernateHelper.deproxy(equipLocal, Equip.class);
			partit.setEquipLocal(equipLocal);
			Hibernate.initialize(equipVisitant);
			equipVisitant = HibernateHelper.deproxy(equipVisitant, Equip.class);
			partit.setEquipVisitant(equipVisitant);
			Hibernate.initialize(estadi);
			estadi = HibernateHelper.deproxy(estadi, Estadi.class);
			partit.setEstadi(estadi);
			partits2.add(partit);
		}
		
		return partits2;
		
	}
	
	@Transactional(readOnly = true)
	public Partit deproxyJornada(Partit partit){
		//Jornada
		Jornada jornada = partit.getJornada();
		Hibernate.initialize(jornada);
		jornada = HibernateHelper.deproxy(jornada, Jornada.class);
		partit.setJornada(jornada);
		
		return partit;
	}
	
	@SuppressWarnings("deprecation")
	@Transactional(readOnly = true)
	public Partit deproxyJornadaLock(Partit partit){
		this.getSessionFactory().getCurrentSession().lock(partit, LockMode.NONE);
		//Jornada
		Jornada jornada = partit.getJornada();
		Hibernate.initialize(jornada);
		jornada = HibernateHelper.deproxy(jornada, Jornada.class);
		partit.setJornada(jornada);
		
		return partit;
	}

	@Override
	@Transactional(readOnly=false)
	public void save(Partit partit) {
		this.getSessionFactory().getCurrentSession().saveOrUpdate(partit);
	}
	
	@SuppressWarnings("unchecked")
	@Transactional(readOnly = true)
	public List<Partit> findPartitByLocalIVisitant(Long idLocal, Long idVisitant) {
		 return this.getSessionFactory().getCurrentSession().createCriteria(Partit.class)
				.add(Restrictions.eq("equipLocal.idEquip", idLocal))
				.add(Restrictions.eq("equipVisitant.idEquip", idVisitant))
				.list();
	}
}
